import { createPortal } from "react-dom";
import { PdfJs } from "../../core";

import PageThumbnailContainer from "./PageThumbnailContainer";
import PrintStatus from "./PrintStatus";
import { FC, useEffect, useMemo } from "react";

interface PrintZoneProps {
  doc: PdfJs.PdfDocument;
  numLoadedPages: number;
  pageHeight: number;
  pageWidth: number;
  printStatus: PrintStatus;
  rotation: number;
  onCancel(): void;
  onLoad(): void;
}

const PrintZone: FC<PrintZoneProps> = ({
  doc,
  numLoadedPages,
  pageHeight,
  pageWidth,
  printStatus,
  rotation,
  onCancel,
  onLoad,
}) => {
  const canvas = useMemo(
    () => document.createElement("canvas") as HTMLCanvasElement,
    []
  );

  const container = useMemo(() => {
    const div = document.createElement("div");
    div.classList.add("rpv-print__zone");
    document.body.appendChild(div);
    return div;
  }, []);

  useEffect(() => {
    if (printStatus === PrintStatus.Ready) {
      document.documentElement.classList.add("rpv-print__html-printing");
      document.body.classList.add("rpv-print__body-printing");
      window.print();
    }

    // Handle the case user clicks the `Cancel` button in the print window
    const handler = (): void => {
      if (printStatus === PrintStatus.Ready) {
        document.documentElement.classList.remove("rpv-print__html-printing");
        document.body.classList.remove("rpv-print__body-printing");

        // Remove the container
        if (container.parentElement) {
          container.parentElement.removeChild(container);
        }

        // Cleanup
        canvas.height = 0;
        canvas.width = 0;

        // Remove the handler
        document.removeEventListener("mousemove", handler);

        onCancel();
      }
    };
    document.addEventListener("mousemove", handler);

    return (): void => document.removeEventListener("mousemove", handler);
  }, [printStatus]);

  // Don't append the pages to the `body` directly
  // Otherwise, it will cause a weird issue such as we can't open any popover
  return createPortal(
    <>
      {Array(Math.min(numLoadedPages + 1, doc.numPages))
        .fill(0)
        .map((_, index) => (
          <PageThumbnailContainer
            key={index}
            canvas={canvas}
            doc={doc}
            pageHeight={pageHeight}
            pageIndex={index}
            pageWidth={pageWidth}
            rotation={rotation}
            onLoad={onLoad}
          />
        ))}
      <style
        dangerouslySetInnerHTML={{
          __html: `@page { size: ${pageWidth}pt ${pageHeight}pt }`,
        }}
      />
    </>,
    container
  );
};

export default PrintZone;
